package br.com.velp.projeto.dao;

import br.com.velp.projeto.entidade.EntidadePadrao;
import br.com.velp.projeto.exception.DAOException;
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import org.apache.log4j.Logger;
import org.hibernate.HibernateException;
import org.hibernate.Session;

public class GenericDAO<T extends EntidadePadrao> {
    
    private Session session;
    private Class<T> clazz;
    private Logger logger;

    public GenericDAO() {
        
        this.logger = Logger.getLogger(GenericDAO.class);  
        this.clazz = (Class<T>) ((ParameterizedType) getClass()  
                                .getGenericSuperclass()).getActualTypeArguments()[0];  
        
    }
    
    public T salvar(T value) {
        
        try {
            this.session.save(value);
            return value;
        } catch (HibernateException ex) {
            this.logger.error("ERRO AO TENTAR SALVAR " + this.clazz.getSimpleName() + ": ", ex);
            throw new DAOException(ex.getCause() != null ? ex.getCause().getMessage() : "");
        } catch (Exception ex) {
            this.logger.error("ERRO AO EXCLUIR ", ex);
            throw new DAOException(ex.getMessage());
        }
        
    }
    
    public void atualizar(T value) {
        
        try {
            this.session.update(value);
            this.session.flush();
        } catch (HibernateException ex) {
            this.logger.error("ERRO AO TENTAR ATUALIZAR " + this.clazz.getSimpleName() + " COM ID " + value.getId() + ": ", ex);
            throw new DAOException(ex.getCause() != null ? ex.getCause().getMessage() : "");
        } catch (Exception ex) {
            this.logger.error("ERRO AO EXCLUIR ", ex);
            throw new DAOException(ex.getMessage());
        }
        
    }
    
    public T obterPorId(Serializable id) {
        
        try {
            return (T) this.session.get(this.clazz, id);
        } catch (HibernateException ex) {
            this.logger.error("ERRO AO TENTAR RECUPERAR " + this.clazz.getSimpleName() + " COM ID " + id + ": ", ex);
            throw new DAOException(ex.getCause() != null ? ex.getCause().getMessage() : "");
        } catch (Exception ex) {
            this.logger.error("ERRO AO EXCLUIR ", ex);
            throw new DAOException(ex.getMessage());
        }
        
    }
    
    public void excluir(T value) {
        
        try {
            this.session.delete(value);
            this.session.flush();
        } catch (HibernateException ex) {
            this.logger.error("ERRO AO EXCLUIR ", ex);
            throw new DAOException(ex.getCause() != null ? ex.getCause().getMessage() : "");
        } catch (Exception ex) {
            this.logger.error("ERRO AO EXCLUIR ", ex);
            throw new DAOException(ex.getMessage());
        }
        
    }
    
    public Session getSession() {
        return this.session;
    }

    public void setSession(Session session) {
        this.session = session;
    }
    
    public Logger getLogger() {
        return this.logger;
    }
    
}
